﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace AsyncAwaitTester
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private readonly HttpClient httpClient = new HttpClient();
        public MainWindow()
        {
            InitializeComponent();
        }

        #region 公共

        private void ReportResult(string result)
        {
            _txtResult.Text += result;
        }

        private string DownloadSync(string url)
        {
            var response = httpClient.GetAsync(url).GetAwaiter().GetResult();
            var responsePayloadBytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
            return $"从{url}下载完成，大小={responsePayloadBytes.Length}。\n";
        }

        #endregion

        #region 同步

        private void ButtonSync_Click(object sender, RoutedEventArgs e)
        {
            _txtResult.Text = "";
            var stopwatch = Stopwatch.StartNew();
            DownloadSync();
            _txtResult.Text += $"使用时间：{stopwatch.Elapsed}\n";
        }

        private void DownloadSync()
        {
            foreach (var item in Contents.WebSiteList)
            {
                var result = DownloadSync(item);
                ReportResult(result);
            }
        }

        #endregion

        #region 异步

        private async void ButtonAsync_Click(object sender, RoutedEventArgs e)
        {
            _txtResult.Text = "";
            var stopwatch = Stopwatch.StartNew();
            await DownloadAsync();
            _txtResult.Text += $"使用时间：{stopwatch.Elapsed}\n";
        }

        private async Task DownloadAsync()
        {
            foreach (var item in Contents.WebSiteList)
            {
                var result = await Task.Run(() => DownloadSync(item));
                ReportResult(result);
            }
        }

        #endregion

        #region 异步并发  

        private async void ButtonAsyncConc_Click(object sender, RoutedEventArgs e)
        {
            _txtResult.Text = "";
            var stopwatch = Stopwatch.StartNew();
            await DownloadAsyncConc();
            _txtResult.Text += $"使用时间：{stopwatch.Elapsed}\n";
        }

        private async Task DownloadAsyncConc()
        {
            List<Task<string>> downloadTaskList = new List<Task<string>>();
            foreach (var item in Contents.WebSiteList)
            {
                downloadTaskList.Add(Task.Run(() => DownloadSync(item)));
            }
            var results = await Task.WhenAll(downloadTaskList);
            foreach (var result in results)
            {
                ReportResult(result);
            }
        }

        #endregion

        #region 异步并发等待

        private async void ButtonAsyncConcAwait_Click(object sender, RoutedEventArgs e)
        {
            _txtResult.Text = "";
            var stopwatch = Stopwatch.StartNew();
            await DownloadAsyncConcAwait();
            _txtResult.Text += $"使用时间：{stopwatch.Elapsed}\n";
        }
        
        private async Task DownloadAsyncConcAwait()
        {
            List<Task<string>> downloadTaskList = new List<Task<string>>();
            foreach (var item in Contents.WebSiteList)
            {
                downloadTaskList.Add(Task.Run(() => DownloadAsyncConcAwait(item)));
            }
            var results = await Task.WhenAll(downloadTaskList);
            foreach (var result in results)
            {
                ReportResult(result);
            }
        }

        private async Task<string> DownloadAsyncConcAwait(string url)
        {
            var response = await httpClient.GetAsync(url);
            var responsePayloadBytes = await response.Content.ReadAsByteArrayAsync();
            return $"从{url}下载完成，大小={responsePayloadBytes.Length}。\n";
        }

        #endregion

    }
}
